// 导入一系列用于类型判断的工具函数
import { isArray, isFunction, isObject, isString, isNullOrUnDef } from '@/utils/is';
// 导入Vue的unref函数，用于获取响应式的引用
import { unref } from 'vue';
// 导入Vue的Ref和ComputedRef类型
import type { Ref, ComputedRef } from 'vue';
// 导入FormSchema类型定义
import type { FormSchema } from '../types/form';
// 导入lodash-es的set函数，用于设置对象的嵌套属性
import { set } from 'lodash-es';

// 定义UseFormValuesContext接口，包含表单模型和schema的引用
interface UseFormValuesContext {
  defaultFormModel: Ref<any>; // 默认表单模型的响应式引用
  getSchema: ComputedRef<FormSchema[]>; // 获取表单schema的计算属性
  formModel: Recordable; // 表单模型
}

/**
 * strShiftObject函数，用于变异目标对象
 * @param key 要变异的键路径
 * @param value 要设置的值
 * @param target 目标对象
 * @returns 如果变异成功，返回true，否则返回false
 */
function strShiftObject(key: string, value: any, target: Recordable) {
  const pattern = /^\{(.+)}$/; // 正则表达式，用于匹配花括号内的键路径
  if (pattern.test(key)) {
    // 如果键是花括号包围的字符串
    const match = key.match(pattern); // 匹配键路径
    if (match && match[1]) {
      // 如果匹配成功
      const keys = match[1].split(','); // 分割键路径为数组
      value = isObject(value) ? value : {}; // 确保value是对象
      keys.forEach((k) => {
        // 遍历键数组
        set(target, k.trim(), value[k.trim()]); // 设置目标对象的嵌套属性
      });
      return true; // 变异成功
    }
  }
}

/**
 * useFormValues函数，用于处理表单值
 * @param context UseFormValuesContext的实例
 * @returns 包含handleFormValues和initDefault方法的对象
 */
export function useFormValues({ defaultFormModel, getSchema, formModel }: UseFormValuesContext) {
  // 处理表单值的函数
  function handleFormValues(values: Recordable) {
    if (!isObject(values)) {
      // 如果values不是对象，则返回空对象
      return {};
    }
    const res: Recordable = {}; // 初始化结果对象
    for (const item of Object.entries(values)) {
      // 遍历values的键值对
      let [, value] = item; // 解构value
      const [key] = item; // 解构key
      if (
        // 如果key为空，value是空数组，函数，或者undefined/null，则跳过
        !key ||
        (isArray(value) && value.length === 0) ||
        isFunction(value) ||
        isNullOrUnDef(value)
      ) {
        continue;
      }
      // 如果value是字符串，则删除前后空格
      if (isString(value)) {
        value = value.trim();
      }
      if (!strShiftObject(key, value, res)) {
        // 如果strShiftObject没有变异对象，则使用set函数设置值
        set(res, key, value);
      }
    }
    return res; // 返回处理后的表单值对象
  }

  // 初始化默认值的函数
  function initDefault() {
    const schemas = unref(getSchema); // 获取schema数组
    const obj: Recordable = {}; // 初始化对象用于存储默认值
    schemas.forEach((item) => {
      // 遍历schema数组
      const { defaultValue } = item; // 获取默认值
      if (!isNullOrUnDef(defaultValue)) {
        // 如果默认值存在
        obj[item.field] = defaultValue; // 设置默认值
        formModel[item.field] = defaultValue; // 设置表单模型的值
      }
    });
    defaultFormModel.value = obj; // 设置默认表单模型的值
  }

  return { handleFormValues, initDefault }; // 返回包含处理表单值和初始化默认值的方法的对象
}
